//
//  BLEBase.swift
//  Clock
//
//  Created by 方强 on 16/7/2.
//  Copyright © 2016年 MT. All rights reserved.
//

import UIKit
import CoreBluetooth

public class BLEBase: NSObject, CBPeripheralDelegate{
    func onScanOver(errocode: ErroCode?) {
        
    }

    private var manager:MTBLEManager!;
    private var device: MTBLEDevice?;
    private var callback: BLEBaseCallback!;
    private var scanCallback: MTBLEManager_ScanCallback!;
    init(manager:MTBLEManager) {
        super.init();
        self.manager = manager;
        
        self.scanCallback = MTBLEManager_ScanCallback();
        
        self.scanCallback.onScan = onScan;
        self.scanCallback.onScanFail = onScanFail;
        
        self.connectCallback = MTBLEManager_ConnectCallback();
        
        self.connectCallback.onConnect = onConnectfunc;
        self.connectCallback.onDisConnect  = onDisConnectfunc;
        
    }
    
    // 通过mac连接
    private var connectMac:String! = "";
    private var usersetconnectRetryTimes:Int=0;
    private var connectRetryTimes:Int=0;
    public func connect(mac:String!, callback: BLEBaseCallback, retryTimes:Int) -> ErroCode?{
        if(!manager.isEnable()){
            return ErroCode.ERROMAP["bleunable"]; // 没有开启蓝牙
        }
        
        // 判断是否有任务已经启动了连接
        if (worktype != WORKTYPE.free) {
            return ErroCode.ERROMAP["busy"]; // 忙状态
        }
        
        self.callback = callback;
        
        if((device != nil) && (mac == self.connectMac)){  // 还是老设备,就直接通过设备进行连接，不需要重新扫描
            MTTools.logout(log: "连接老设备->\(retryTimes)");
            return connect(device: device, callback: callback, retryTime: retryTimes);
        }
        
        MTTools.logout(log: "连接扫描");
        self.connectMac = mac.uppercased(); // 保存设置的连接参数
        self.usersetconnectRetryTimes = retryTimes;
        self.connectRetryTimes = self.usersetconnectRetryTimes;

        worktype = WORKTYPE.scanning;
        startTimer(selector: #selector(scanTimeoutRunnable), timeout: 5);  // 5秒
        manager.startScan(scanmode: MTBLEManager_ScanMode.FAST, serviceUuids: nil, scanCallback: self.scanCallback, worktime: 10, sleeptime: 1, scanTimes: 0);
        
        return ErroCode.ERROMAP["OK"];
    }
    
    func onScan(device: MTBLEDevice){
        if(device.getMac() == nil){
            return;
        }
        if(device.getMac()?.uppercased() == self.connectMac.uppercased()){
            self.device = device;
            manager.stopScan();
            stopTimer();
            worktype = WORKTYPE.free;
            connect(device: self.device, callback: callback, retryTime: self.connectRetryTimes);
        }
    }

    func onScanFail(erro: ErroCode?){
        worktype = WORKTYPE.free;
        stopTimer(); // 移除连接超时
        
        callback.onBaseConnect?(self, ErroCode.ERROMAP["scanerro"]!);
    }
    
    // 通过device连接
    private var connectCallback:MTBLEManager_ConnectCallback!;
    public func connect(device: MTBLEDevice!, callback: BLEBaseCallback, retryTime:Int) -> ErroCode?{
        self.device = device;  // 保存设置的连接参数
        self.usersetconnectRetryTimes = retryTime;
        self.connectRetryTimes = self.usersetconnectRetryTimes;
        self.callback = callback;
        
        MTTools.logout(log: "连接");

        return __connect();
    }
    
    // 连接
    private func __connect() -> ErroCode?{
        
        MTTools.logout(log: "connectRetryTimes->\(connectRetryTimes)");
        if (connectRetryTimes < 0) {
            worktype = WORKTYPE.free;
            callback.onBaseConnect?(self,ErroCode.ERROMAP["timeout"]!);
//            disConnect();
            return ErroCode.ERROMAP["OK"];
        }
        
        if (self.connectRetryTimes != self.usersetconnectRetryTimes) { // 不是第一次就是重试
            callback.reTryConnect?(self, self.connectRetryTimes);
        }
        
        worktype = WORKTYPE.connectting;
        manager.stopScan(); // 停止扫描
        
        connectRetryTimes -= 1;
        
        device!.getDevice().delegate = self;
        
        isRunning = false;
        
        manager.connect(peripheral: device!.getDevice(), callback: connectCallback);
        
        listenedCharacts.removeAll();
        return ErroCode.ERROMAP["OK"];
    }

    // 断开连接
    public func disConnect() -> Bool{
        MTTools.logout(log: "disConnect");
        
        if(worktype == WORKTYPE.scanning){ // 如果还在扫描的话，则停止扫描
            manager.stopScan();
            worktype = WORKTYPE.free;
            stopTimer();
            return true;
        }
        
        if(device == nil){
            return true;
        }
    
        // 删除所有任务
        for BLEBaseAction2 in taskList {
            BLEBaseAction2.onCancel?(BLEBaseAction2);
        }
        taskList.removeAll();
    
        if (!isConnected()) {
            worktype = WORKTYPE.free;
            manager.disConect(peripheral: device!.getDevice());
            callback.onManualDisConnect?(self, ErroCode.ERROMAP["OK"]!);
            return true;
        }
    
        if (device?.getDevice() != nil) {
            worktype = WORKTYPE.disconnectting;
            manager.disConect(peripheral: device!.getDevice());
            return true;
        }
        return false;
    }
    
    // 读取rssi
    public func peripheral(_ peripheral: CBPeripheral, didReadRSSI RSSI: NSNumber, error: Error?){
        if (taskList.count == 0) {
            return;
        }
        let task2 = taskList[0];
        if ((task2.getActiontype() != BLEBaseAction_ActionType.READRSSI)) {
            return;
        }
        let task = task2 as! ReadRssiAction;
        
        task.setStatues(statues: BLEBaseAction_ActionStatues.DONE);
        startNewTask(selector: #selector(goonTask));  // 继续任务
        if (error != nil) {
            task.onFail?(task, ErroCode.ERROMAP["unknow"]!);
        } else {
            task.onGetRssi?(task, RSSI.intValue);
        }
    }
    
    // 发现服务
    public func peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?){
        MTTools.logout(log: "didDiscoverServices");
        
        if (taskList.count == 0) {
            return;
        }
        let task2 = taskList[0];
        if (task2.getActiontype() != BLEBaseAction_ActionType.DISCOVERSERVICE) {
            return;
        }
        let task = task2 as! DiscoverServicesAction;
        
        task.setStatues(statues: BLEBaseAction_ActionStatues.DONE);
        startNewTask(selector: #selector(goonTask));  // 继续任务
        if (error != nil) {
            task.onFail?(task, ErroCode.ERROMAP["unknow"]!);
        } else {
            task.onSuccess?(task);
        }
    }
    
    // 发现特征值
    public func peripheral(_ peripheral: CBPeripheral, didDiscoverCharacteristicsFor service: CBService, error: Error?){
        MTTools.logout(log: "didDiscoverCharacteristicsForService");
        if (taskList.count == 0) {
            return;
        }
        let task2 = taskList[0];
        if (task2.getActiontype() != BLEBaseAction_ActionType.DISCOVERVHARACTS) {
            return;
        }
        let task = task2 as! DiscoverCharactsAction;
        
        task.setStatues(statues: BLEBaseAction_ActionStatues.DONE);
        startNewTask(selector: #selector(goonTask));  // 继续任务
        if (error != nil) {
            task.onFail?(task, ErroCode.ERROMAP["unknow"]!);
        } else {
            task.onSuccess?(task);
        }
    }
    
    // 更新特征值
    public func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?){
        let datas = characteristic.value;
        
        // 读特征值操作
        if((taskList.count != 0) && (taskList[0].getActiontype() == BLEBaseAction_ActionType.READCHACT) && ((taskList[0] as! ReadCharactAction).getCharact() === characteristic)){
            let task = taskList[0] as! ReadCharactAction;
            task.setStatues(statues: BLEBaseAction_ActionStatues.DONE);
            startNewTask(selector: #selector(goonTask));   // 继续任务
            if(error != nil){
                task.onFail?(task, ErroCode.ERROMAP["unknow"]!);
            }else{
                if(datas == nil){
                    task.onReadDatas?(task, characteristic, nil);
                }else{
                    task.onReadDatas?(task, characteristic, datas);
                }
            }
        }
        
        // 通知操作
        if (taskList.count != 0) {
            let task2 = taskList[0];
            if (task2.getActiontype() == BLEBaseAction_ActionType.WRITECHACTWITHACK) {
                let task = task2 as! WriteCharactWithAckAction;
                if (task.getReviceCharact() === characteristic) { // 不是此任务
                    task.onReciveDatas?(task, characteristic, datas);
                    if (task.getStatues() == BLEBaseAction_ActionStatues.DONE) {
                        startNewTask(selector: #selector(goonTask));
                    }
                    return;
                }
            }
            
            if(task2.getActiontype() == BLEBaseAction_ActionType.SENDBIGDATAS){
                let task = task2 as! SendBigDatasAction;
                
                if((characteristic != task.getReviceCharact()) || (datas == nil) || (datas?.count != 2)){
                    return;
                }
                if((task.getSendingIndex()-1) != (MTTools.convertUint16(hb: datas![0], lb: datas![1]))){
                    task.setStatues(statues: BLEBaseAction_ActionStatues.DONE);
                    task.onFail?(task, ErroCode.ERROMAP["lostdatas"]!);
                }
                goonTask();
                return;
            }
        }
        
        for bluetoothGattCharacteristic in listenedCharacts {
            if (characteristic === bluetoothGattCharacteristic) { // 在被监听列表
                callback.onCharactChanged?(self, characteristic, datas);
            }
        }
    }
    
    // 写特征值
    public func peripheral(_ peripheral: CBPeripheral, didWriteValueFor characteristic: CBCharacteristic, error: Error?){
        MTTools.logout(log: "didWriteValueForCharacteristic");
        if (taskList.count == 0) {
            return;
        }
        let task2 = taskList[0];
        if (task2.getActiontype() == BLEBaseAction_ActionType.SENDBIGDATAS) { // 发送大数据时，不需要做任何响应
            return;
        }
        if ((task2.getActiontype() != BLEBaseAction_ActionType.WRITECHACT)
            && (task2.getActiontype() != BLEBaseAction_ActionType.WRITECHACTWITHACK)) {
            return;
        }
        //					WriteCharactAction task = (WriteCharactAction) task2;
        var charact:CBCharacteristic!;
        
        if(task2.getActiontype() == BLEBaseAction_ActionType.WRITECHACT){
            charact = (task2 as! WriteCharactAction).getCharact();
        }else{
            charact = (task2 as! WriteCharactWithAckAction).getSendCharact();
        }
        
        if (charact !== characteristic) { // 不是此任务
            return;
        }
        if (error != nil) { // 设置可通知失败
            task2.setStatues(statues: BLEBaseAction_ActionStatues.DONE);
            task2.onFail?(task2, ErroCode.ERROMAP["unknow"]!);
        }
        
        var deleytime:Double = 0.0; // 需要的延迟
        
        if(characteristic.properties.contains(CBCharacteristicProperties.write)){
        }else{
            deleytime = task2.getOption().getWaittime();
        }
        
        startTimer(selector: #selector(goonTask), timeout: deleytime);
    }
    
    // 更新可通知属性
    public func peripheral(_ peripheral: CBPeripheral, didUpdateNotificationStateFor characteristic: CBCharacteristic, error: Error?){
        MTTools.logout(log: "didUpdateNotificationStateForCharacteristic");
        if (taskList.count == 0) {
            return;
        }
        let task2 = taskList[0];
        if ((task2.getActiontype() != BLEBaseAction_ActionType.SETNOTIFY)) {
            return;
        }
        let task = task2 as! SetNotifyAction;
        
        task.setStatues(statues: BLEBaseAction_ActionStatues.DONE);
        startNewTask(selector: #selector(goonTask));  // 继续任务
        if (error != nil) {
            MTTools.logout(log: "peripheral erro->\(error)");
            if(task.onFail != nil){
                task.onFail!(task, ErroCode.ERROMAP["unknow"]!);
            }
        } else {
            if(task.onSuccess != nil){
                task.onSuccess!(task);
            }
        }
    }
    
    // 发现Descriptors
    public func peripheral(_ peripheral: CBPeripheral, didDiscoverDescriptorsFor characteristic: CBCharacteristic, error: Error?){
        
    }
    
    // 写Descriptor
    public func peripheral(_ peripheral: CBPeripheral, didWriteValueFor descriptor: CBDescriptor, error: Error?){
        
    }
    
    // 获取所有services
    public func getAllServices() -> [CBService]?{
        if((device == nil) || (device?.getDevice()==nil)){
            return nil;
        }
        return device?.getDevice().services;
    }
    
    // 获取某个特定的service
    public func getService(uuid:String!) -> CBService?{
        for service in (device?.getDevice().services)! {  // 遍历寻找service
            if(service.uuid.uuidString == uuid){
                return service;
            }
        }
        return nil;
    }
    
    // 获取某个特定的特征值
    public func getCharact(serviceuuid:String, charactuuid:String) -> CBCharacteristic?{
        let service = getService(uuid: serviceuuid);
        if (service == nil) {
            return nil;
        }
        
        for charact in (service?.characteristics)! {
            if(charact.uuid.uuidString == charactuuid){
                return charact;
            }
        }
        
        return nil;
    }
    
    // 连接回调
    private func onConnectfunc(peripheral:CBPeripheral!, errocode:ErroCode?) {
        MTTools.logout(log: "onConnect->\(errocode?.getMsg())");

        if (worktype == WORKTYPE.free) { // 不做任何反馈
            manager.disConect(peripheral: peripheral);
            MTTools.logout(log: "过时的连接操作");
            return;
        }
        
        if (errocode?.getCode() != 0) { // 连接失败,重连
            if (worktype == WORKTYPE.connectting) {
                MTTools.logout(log: "连接失败,重连");
                __connect();
            }
        } else { // 连接成功
            self.worktype = WORKTYPE.free;
            callback.onBaseConnect?(self, ErroCode.ERROMAP["OK"]!);
        }
    }
    
    // 断开连接
    private func onDisConnectfunc(peripheral:CBPeripheral!, errocode:ErroCode?) {
        MTTools.logout(log: "onDisConnect");
        
        if (worktype == WORKTYPE.connectting) { // 连接时断开，则重连
            __connect();
        } else if (worktype == WORKTYPE.disconnectting) { // 如果是主动断开
            if (errocode?.getCode() != 0) { // 断开失败
                MTTools.logout(log: "断开失败");
                callback.onManualDisConnect?(self, ErroCode.ERROMAP["unforturedis"]!);
            } else {
                worktype = WORKTYPE.free;
                callback.onManualDisConnect?(self, ErroCode.ERROMAP["OK"]!);
            }
        }else { // 意外断开
            callback.onDisConnect?(self, ErroCode.ERROMAP["OK"]!);
        }
    }
    
    // 查看连接状态
    public func isConnected() -> Bool{
        if (device == nil) {
            return false;
        }
        if (device?.getDevice().state == CBPeripheralState.connected) {
            return true;
        } else {
            return false;
        }
    }
    
    // 任务列表
    private var setRunFlag = true; // 任务是否运行标志
    private var isRunning = false; // 任务运行状态
    private var taskList:[BLEBaseAction] = [BLEBaseAction](); // 任务列表
    
    public func addNewAction(action:BLEBaseAction!) -> ErroCode?{
        
        if (!isConnected()) { // 没有连接的情况
            MTTools.logout(log: "没有连接的情况");
            return ErroCode.ERROMAP["unconnect"];
        }
        
        taskList.append(action);
        
        if (!isRunning) { // 如果没有开始跑任务，则开始运行
            MTTools.logout(log: "继续运行任务");
            goonTask();
        }
        
        return ErroCode.ERROMAP["OK"];
    }
    
    // 暂停任务
    public func stop() {
        self.setRunFlag = false;
    }
    
    // 开始任务
    public func start() {
        if (self.setRunFlag) {
            return;
        }
        self.setRunFlag = true;
        goonTask();
    }
    
    // 继续运行任务
    func goonTask() {
//        MTTools.logout(log: "goonTask");
        stopTimer();
        isRunning = true;
        if (!setRunFlag) { // 如果用户设置了停止任务运行
            isRunning = false;
            return;
        }
        
        if (taskList.count == 0) { // 没有任务需要运行
            isRunning = false;
            return;
        }
        
        if (!isConnected()) { // 如果失去连接
            isRunning = false;
            return;
        }
        
        // 寻找可用任务
        var i=0;
        while i < taskList.count {
            
            if (taskList[i].getStatues() == BLEBaseAction_ActionStatues.CANCEL) { // 如果该任务被取消，则从任务队伍里面删除掉
                taskList.remove(at: i);
                continue;
            }
            
            if (taskList[i].getStatues() == BLEBaseAction_ActionStatues.DONE) { // 如果该任务完成，则从任务队伍里面删除掉
                taskList.remove(at: i);
                continue;
            }
            i += 1;
        }

        if (taskList.count == 0) { // 没有任务了
            isRunning = false;
            return;
        }
        
        let task = taskList[0]; // 获取需要执行的任务
        
        // 读特征值任务
        if (task.getActiontype() == BLEBaseAction_ActionType.READCHACT) {
            task.setStatues(statues: BLEBaseAction_ActionStatues.RUNING); // 设置成正在运行
            startTimer(selector: #selector(tasktimeoutRunnable), timeout: task.getOption().getTimeout());
            
            if(task.onStart != nil){
                task.onStart!(task);
            }
            device?.getDevice().readValue(for: (task as! ReadCharactAction).getCharact()!);
            return;
        }
        
        // 写特征值任务
        if(task.getActiontype() == BLEBaseAction_ActionType.WRITECHACT) {
            startTimer(selector: #selector(tasktimeoutRunnable), timeout: task.getOption().getTimeout());
            if (task.getStatues() == BLEBaseAction_ActionStatues.WAITTING) {
                task.setStatues(statues: BLEBaseAction_ActionStatues.RUNING);
                task.onStart?(task);
            }
            let writetask = task as! WriteCharactAction;
            task.setStatues(statues: BLEBaseAction_ActionStatues.RUNING);
            let senddata = writetask.getPerdatas();
                
            if (senddata == nil) { // 已经发送完毕这条数据
                writetask.setStatues(statues: BLEBaseAction_ActionStatues.DONE);
                task.onSuccess?(task);
                startTimer(selector: #selector(goonTask), timeout: 0); // 采用这种方式进行回调，从而防止出现递归
                return;
            }
            
            MTTools.logout(log: "发送无反馈数据->\(MTTools.convertDataToString(data: senddata)!)");
            let c = writetask.getCharact()!;
            
            if(c.properties.contains(CBCharacteristicProperties.write)){
                device?.getDevice().writeValue(senddata!, for: c, type: CBCharacteristicWriteType.withResponse);
            }else{
                device?.getDevice().writeValue(senddata!, for: c, type: CBCharacteristicWriteType.withoutResponse);
            }
            return;
        }
        
        // 发现服务
        if(task.getActiontype() == BLEBaseAction_ActionType.DISCOVERSERVICE){
            MTTools.logout(log: "开始发现服务");
            task.setStatues(statues: BLEBaseAction_ActionStatues.RUNING); // 设置成正在运行
            startTimer(selector: #selector(tasktimeoutRunnable), timeout: task.getOption().getTimeout());  // 发现服务不需要超时判断
            task.onStart?(task);
            device?.getDevice().discoverServices((task as! DiscoverServicesAction).getServiceUUIDS());
            return;
        }
        
        // 发现特征值
        if(task.getActiontype() == BLEBaseAction_ActionType.DISCOVERVHARACTS){
            MTTools.logout(log: "开始发现特征值");
            task.setStatues(statues: BLEBaseAction_ActionStatues.RUNING); // 设置成正在运行
            startTimer(selector: #selector(tasktimeoutRunnable), timeout: task.getOption().getTimeout());  // 发现服务不需要超时判断
            task.onStart?(task);
            let task_tmp = task as! DiscoverCharactsAction;
            device?.getDevice().discoverCharacteristics(task_tmp.getCharactuuids(), for: task_tmp.getService());
            return;
        }
        
        // 写descriptor
        if (task.getActiontype() == BLEBaseAction_ActionType.WRITEDESCRIPTOR) {
            startTimer(selector: #selector(BLEBase.tasktimeoutRunnable), timeout: task.getOption().getTimeout());
            task.setStatues(statues: BLEBaseAction_ActionStatues.RUNING);
            if (task.getStatues() == BLEBaseAction_ActionStatues.WAITTING) {
                task.onStart?(task);
            }
            
            let descriptor = (task as! WriteDescriptorAction).getDescriptor();
            let data = (task as! WriteDescriptorAction).getData();
            device?.getDevice().writeValue(data!, for: descriptor!);
            return;
        }
        
        // 读descriptor通知
        if (task.getActiontype() == BLEBaseAction_ActionType.READDESCRIPTOR) {
            task.setStatues(statues: BLEBaseAction_ActionStatues.RUNING); // 设置成正在运行
            startTimer(selector: #selector(BLEBase.tasktimeoutRunnable), timeout: task.getOption().getTimeout());
            task.onStart?(task);
            
            device?.getDevice().readValue(for: (task as! ReadDescriptorAction).getDescriptor()!);
            return;
        }
        
        // 读取rssi
        if(task.getActiontype() == BLEBaseAction_ActionType.READRSSI){
            task.setStatues(statues: BLEBaseAction_ActionStatues.RUNING); // 设置成正在运行
            startTimer(selector: #selector(tasktimeoutRunnable), timeout: task.getOption().getTimeout());
            task.onStart?(task);
            device?.getDevice().readRSSI();
            return;
        }
        
        // 设置可通知属性
        if(task.getActiontype() == BLEBaseAction_ActionType.SETNOTIFY){
            task.setStatues(statues: BLEBaseAction_ActionStatues.RUNING); // 设置成正在运行
            startTimer(selector: #selector(tasktimeoutRunnable), timeout: task.getOption().getTimeout());
            task.onStart?(task);
            let task2 = task as! SetNotifyAction;
            MTTools.logout(log: "开始设置可通知");
            device?.getDevice().setNotifyValue(task2.isEnable(), for: task2.getCharact()!);
            return;
        }
        
        // 写有反馈特征值任务
        if (task.getActiontype() == BLEBaseAction_ActionType.WRITECHACTWITHACK) {
            startTimer(selector: #selector(tasktimeoutRunnable), timeout: task.getOption().getTimeout());
            if (task.getStatues() == BLEBaseAction_ActionStatues.WAITTING) {
                task.setStatues(statues: BLEBaseAction_ActionStatues.RUNING);
                task.onStart?(task);
            }
            let writetask = task as! WriteCharactWithAckAction;
            task.setStatues(statues: BLEBaseAction_ActionStatues.RUNING);
            let senddata = writetask.getPerdatas();
            
            if (senddata == nil) { // 已经发送完毕这条数据,等待用户停止
                return;
            }
            MTTools.logout(log: "发送等待反馈数据->\(MTTools.convertDataToString(data: senddata)!)");
            let charact = writetask.getSendCharact();
            
            if(charact!.properties.contains(CBCharacteristicProperties.write)){
                device?.getDevice().writeValue(senddata!, for: charact!, type: CBCharacteristicWriteType.withResponse);
            }else{
                device?.getDevice().writeValue(senddata!, for: charact!, type: CBCharacteristicWriteType.withoutResponse);
            }
            return;
        }
        
        // 写大数据任务
        if (task.getActiontype() == BLEBaseAction_ActionType.SENDBIGDATAS){
            startTimer(selector: #selector(tasktimeoutRunnable), timeout: task.getOption().getTimeout());
            if (task.getStatues() == BLEBaseAction_ActionStatues.WAITTING) {
                task.setStatues(statues: BLEBaseAction_ActionStatues.RUNING);
                if(task.onStart != nil){
                    task.onStart!(task);
                }
            }
            
            let writetask = task as! SendBigDatasAction;
            task.setStatues(statues: BLEBaseAction_ActionStatues.RUNING);
            let senddata = writetask.getDatas();
            
            if(senddata == nil){
                writetask.setStatues(statues: BLEBaseAction_ActionStatues.DONE);
                writetask.onSuccess?(writetask);
                startTimer(selector: #selector(goonTask), timeout: 0);
                return;
            }
            
            let charact = writetask.getSendCharact();
            if(charact!.properties.contains(CBCharacteristicProperties.write)){
                device?.getDevice().writeValue(senddata!, for: charact!, type: CBCharacteristicWriteType.withResponse);
            }else{
                device?.getDevice().writeValue(senddata!, for: charact!, type: CBCharacteristicWriteType.withoutResponse);
            }
            
            return;
        }
        
        // 没有定义的操作，则直接过滤掉
        task.setStatues(statues: BLEBaseAction_ActionStatues.DONE);
        if(task.onCancel != nil){
            task.onCancel!(task);
        }
        startTimer(selector: #selector(goonTask), timeout: 0);
    }
    
    // 添加被监听的特征值
    private var listenedCharacts:[CBCharacteristic] = [CBCharacteristic]();
    
    public func addListCharact(charact:CBCharacteristic!) {
        for bluetoothGattCharacteristic in listenedCharacts {
            if (charact === bluetoothGattCharacteristic) { // 已经添加过了
                return;
            }
        }
        listenedCharacts.append(charact);
    }
    
    public func removeListCharact(charact:CBCharacteristic!){
        for i in 0...listenedCharacts.count{
            if (charact === listenedCharacts[i]) { // 已经添加过了
                listenedCharacts.remove(at: i);
                break;
            }
        }
    }
    // 删除所有监听列表
    public func removeListCharact() {
        listenedCharacts.removeAll();
    }
    
    // 连接超时处理
    func scanTimeoutRunnable(){
        worktype = WORKTYPE.free;
        manager.stopScan();
        callback.onBaseConnect?(self, ErroCode.ERROMAP["cantfinddevice"]!);
    }
    
    // 任务超时
    func tasktimeoutRunnable() {
        MTTools.logout(log: "任务超时");
        if (taskList.count == 0) {
			return;
        }
        let task = taskList[0]; // 获取需要执行的任务
        if (task.getStatues() != BLEBaseAction_ActionStatues.RUNING) {
            return;
        }
        if(task.onFail != nil){
            task.onFail!(task, ErroCode.ERROMAP["timeout"]!); // 提示超时错误
        }
        task.setStatues(statues: BLEBaseAction_ActionStatues.DONE);
        goonTask();
    }
    
    // 启动定时器
    private var timer:Timer?;
    private func startTimer(selector:Selector!, timeout:TimeInterval){
        stopTimer();  // 如果此时有正在工作的定时器，则取消
        timer = Timer.scheduledTimer(timeInterval: timeout, target: self, selector: selector, userInfo: nil, repeats: false);
    }
    
    // 停止定时器
    private func stopTimer(){
        if((timer != nil) && (timer?.isValid)!){  // 如果此时有正在工作的定时器，则取消
            timer?.invalidate();
        }
    }
    
    // 开启新任务来执行，以免出现递归现象
    private func startNewTask(selector:Selector!){
        startTimer(selector: selector, timeout: 0);
    }
    
    // 工作类型
    private var worktype = WORKTYPE.free;
    
    private enum WORKTYPE {
        case free
        case scanning
        case disconnectting
        case connectting
        case sending
    }
}

public class BLEBaseCallback: NSObject{
    public var onBaseConnect:((BLEBase, ErroCode)->Void)?;
    public var reTryConnect:((BLEBase, Int)->Void)?;
    public var onDisConnect:((BLEBase, ErroCode)->Void)?;
    public var onManualDisConnect:((BLEBase, ErroCode)->Void)?;
    public var onCharactChanged:((BLEBase, CBCharacteristic, Data?)->Void)?;
}
